
//author Aritra Dhar


package test;

import java.util.Collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;

/*
 * I wrote this comparator as TreeSet is based on sorted element
 * It can not sort or organize collections 
 */
class IntegerCollectionComp implements Comparator<Collection<Integer>>
{	 
    @Override
    public int compare(Collection<Integer> e1, Collection<Integer> e2) {
        if(e1.size() > e2.size())
        {
            return 1;
        } else {
            return -1;
        }
    }
}

public class AspectTestCase 
{
	static Random rand = new Random(123456789);
	public static void CHM_safe()
	{
		ConcurrentHashMap<Integer , String> chm = new ConcurrentHashMap<>();
		
		for(int i = 0; i<10000; i++)
		{
			Integer key = rand.nextInt();			
			
			if(chm.containsKey(key))
				key = rand.nextInt();
			
			if(key<1)
				key *= -1;
			
			char[] charStr = new char[10];
			for(int j = 0;j<10;j++)
			{
				int charI = rand.nextInt(127 - 33 + 1) + 33;
				charStr[j] = (char) charI;
			}
			
			String value = String.valueOf(charStr);
			chm.put(key, value);
		}
		
		Iterator<Integer> it = chm.keySet().iterator();
		
		while(it.hasNext())
		{		
			Integer key = it.next();
			
			String val = chm.get(it.next());
			if(key%2 == 0)
				chm.put(key + 1, val);
			else
				chm.remove(key);
		}
	
		System.out.println("Size of HashMap : " +  chm.keySet().size());
		
	}
	
	public static void HS_safe()
	{
		Collection<Collection<Long>> set_container = new HashSet<Collection<Long>>();
		Collection<Iterator<Long>> iter_container = new HashSet<Iterator<Long>>();
		
		for(int i = 0; i<100; i++)
		{
			Collection<Long> c = new HashSet<Long>();
			set_container.add(c);
			
			for(Long j=(long) 0; j<100; j++)
			{
				c.add(j);
			}
			
			for(Long k=(long) 0; k<60; k++)
			{
				Iterator<Long> it = c.iterator();
				iter_container.add(it);
				Long x = (long) 0;
				
				while(it.hasNext())
				{
					x += it.next();
				}
				c.add(x);
			}
			//System.out.println(c);
			
		}
		System.out.println("The size of set_container is " + 
							set_container.size() + 
							" and the size of iter_container is " + iter_container.size());
	}
	
	public static void TS_Unsafe()
	{
		Collection<Collection<Integer>> set_container = new TreeSet<Collection<Integer>>(new IntegerCollectionComp());
		Collection<Iterator<Integer>> iter_container = new HashSet<Iterator<Integer>>();
		
		for(int i = 0; i<10; i++)
		{
			TreeSet<Integer> c = new TreeSet<Integer>();
			set_container.add(c);
			
			for(int j=0; j<10; j++)
			{
				Integer intr = rand.nextInt();
				c.add(intr);
			}
			
			for(int k=0; k<10; k++)
			{
				Iterator<Integer> it = c.descendingIterator();
				iter_container.add(it);
				Integer x = 0;
				
				while(it.hasNext())
				{
					x += it.next();
					c.add(x);
				}
			}
			
		}
		System.out.println("The size of set_container is " + 
							set_container.size() + 
							" and the size of iter_container is " + iter_container.size());
	}
	
	public static void PQ_unsafe()
	{
		Collection<Queue<Integer>> collection_container = new HashSet<Queue<Integer>>(); 
		Collection<Iterator<Integer>> iter_container = new HashSet<Iterator<Integer>>();
	      
		
		for(int i = 0;i<100; i++)
		{
			Queue<Integer> prq = new PriorityQueue<Integer>();
			collection_container.add(prq);
			
			
			for (int j = 0; j < 100; j++)
			{  
				Integer element = rand.nextInt();
				prq.add(element);
			}
			
			for(int k=0; k<10; k++)
			{
				Iterator<Integer> it = prq.iterator();
				iter_container.add(it);
				int x = 0;
				while(it.hasNext())
				{
					x += it.next();
					
					if(x%2 == 0)
						prq.add(x);
					else
						prq.poll();
				}
			}
		}
	      
		System.out.println("The size of collection_container is " + 
				collection_container.size() + 
				" and the size of iter_container is " + iter_container.size());
	}
	
	public static void main(String[] args) 
	{
		/*
		 * Choose any collection and write aspects for it
		 * Concurrent Hash Map
		 * Hash Set
		 * Tree Set
		 * Priority Queue
		 */
		AspectTestCase.CHM_safe();
		//AspectTestCase.HS_safe();
		//AspectTestCase.TS_Unsafe();
		//AspectTestCase.PQ_unsafe();
		
		
		System.exit(0);
	}
}
